package cn.fangline.wo.task.akka.actors;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import cn.fangline.base.util.Constants;
import cn.fangline.base.util.HeaderUtil;
import cn.fangline.base.util.StringUtil;
import cn.fangline.base.util.exception.WrongContainException;
import cn.fangline.wo.model.House;
import cn.fangline.wo.model.HouseImg;
import cn.fangline.wo.model.OriginHouse;
import cn.fangline.wo.task.akka.messages.EndPoint;
import cn.fangline.wo.task.akka.messages.HouseImagePage;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.util.concurrent.RateLimiter;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.jsoup.HttpStatusException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketTimeoutException;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by 抽离 on 2017/6/28 0028.
 */
public class HouseImageActor extends AbstractActor {

    private RateLimiter rateLimiter;
    private final static Logger logger = Logger.getLogger(HouseImageActor.class);


    public HouseImageActor(RateLimiter rateLimiter) {
        this.rateLimiter = rateLimiter;
    }

    @Override
    public Receive createReceive() {
        return
                    receiveBuilder()
                            .match(HouseImagePage.class, this::onReceiveImagePage)
                            .build();
    }


    private void onReceiveImagePage(HouseImagePage houseImagePage) {
        rateLimiter.acquire();//阻塞
            try {
                if(houseImagePage.getCounter() > Constants.RETRY_COUNT){
                    return;
                }
                Document doc = Jsoup.connect(houseImagePage.getUrl().replaceAll("https","http"))
                        .header(Constants.HEADER_NAME, HeaderUtil.getUserAgent())
                        .proxy(new Proxy(Proxy.Type.HTTP
                                , new InetSocketAddress("proxy.abuyun.com", 9010)))
                        .header("Proxy-Authorization", "Basic SE80MDNUNzI3V1QwOThXUDozQzRBOTUxM0RCQ0EyQUZG")
                        .header("Proxy-Switch-Ip", "yes")
                        .timeout(3000)
                        .get();

                Elements notExist = doc.select(".error-info");
                if(!StringUtils.isEmpty(notExist.toString())){
                    //抱歉,您要查看的页面丢失了
                    return;
                }

                Elements verify = doc.select("#verify_page");
                if(verify!=null && verify.size()>0){
                    throw new WrongContainException("请求频繁页面，重试");
                }

                Element switch_wrap = doc.getElementById("switch_wrap");
                if(switch_wrap == null) {
                    System.out.println("doc：" + doc);
                    System.out.println("switch_wrap：" + switch_wrap);
                }
                switch_wrap.select("#zhankeng_first").remove();
                switch_wrap.select("#zhankeng_last").remove();
                Elements l = switch_wrap.select(".switch_list .img_wrap img");
//                List<HouseImg> houseImgs = new ArrayList<>();
                for(Element t : l){
                    HouseImg h = new HouseImg();
                    h.setCityId(houseImagePage.getCityId());
                    h.setHouseId(houseImagePage.getHouseId());
                    h.setImgUrl(t.attr("data-src"));
                    if(StringUtil.isEmpty(h.getImgUrl())){//前两张图片可能为空
                        h.setImgUrl(t.attr("src"));
                    }
                    h.setOriginHouseId(houseImagePage.getOriginHouseId());
                    h.setNet(Constants.ANJUKE);
                    try{
                        h.insert();
                        getSender().tell(new EndPoint(), getSelf());
                    }catch(Exception e){
                        StringWriter errors = new StringWriter();
                        e.printStackTrace(new PrintWriter(errors));
                        logger.error("插入图片出错：" + errors + "url：" + h.getImgUrl());
                        System.out.println("insert img exception：" + e);
                    }
                }

                Elements cevInfoMainLis = doc.select("ul.cev-info-main li");
                String address = null;
                if(cevInfoMainLis!=null && cevInfoMainLis.size()>1){
                    Element li = cevInfoMainLis.get(1);
                    li.select("label").remove();
                    li.select(".ico").remove();
                    address = li.text().replaceAll("[   ]","").trim();
                }
                Integer room = null, hall = null, toilet = null;
                if(cevInfoMainLis!=null && cevInfoMainLis.size()>2){
                    Element li = cevInfoMainLis.get(2);
                    li.select("label").remove();
                    String s = li.text().replaceAll("[   ]","").trim();

                    String reg = "((\\d+)\\u5ba4)*((\\d+)\\u5385)*((\\d+)\\u536b)*";
                    Pattern p = Pattern.compile(reg);
                    Matcher m = p.matcher(s);
                    if(m.find()){
                        try{hall = Integer.parseInt(m.group(4));}catch (Exception e){}
                        try{toilet = Integer.parseInt(m.group(6));}catch (Exception e){}
                        try{room = Integer.parseInt(m.group(2));}catch (Exception e){}
                    }
                }
                String towards = null;
                if(cevInfoMainLis!=null && cevInfoMainLis.size()>4){
                    Element li = cevInfoMainLis.get(4);
                    li.select("label").remove();
                    towards = li.text().replaceAll("[   ]","").trim();
                }
                String decoration = null;
                if(cevInfoMainLis!=null && cevInfoMainLis.size()>6){
                    Element li = cevInfoMainLis.get(6);
                    li.select("label").remove();
                    decoration = li.text().replaceAll("[   ]","").trim();
                }

                OriginHouse oh = new OriginHouse().selectOne(new EntityWrapper<OriginHouse>()
                        .eq("origin_house_id", houseImagePage.getOriginHouseId()));
                if(oh!=null && oh.getId()!=null){
                    if(oh.getRoom()==null){ oh.setRoom(room);}
                    if(oh.getHall()==null){oh.setHall(hall);}
                    if(oh.getToilet()==null){oh.setToilet(toilet);}
                    oh.setAddress(address);
                    oh.setDecoration(decoration);
                    oh.setTowards(towards);
                    oh.updateById();
                    getSender().tell(new EndPoint(), getSelf());
                }else{
                    logger.info("找不到 OriginHouse");
                }

                House h = new House().selectOne(new EntityWrapper<House>()
                        .eq("house_id", houseImagePage.getHouseId()));
                if(h!=null && h.getHouseId()!=null){
                    if(h.getRoom()==null){ h.setRoom(room);}
                    if(h.getHall()==null){h.setHall(hall);}
                    if(h.getToilet()==null){h.setToilet(toilet);}
                    h.setAddress(address);
                    h.setTowards(towards);
//                    h.setDecoration(decoration);
                    h.updateById();
                    getSender().tell(new EndPoint(), getSelf());
                }else{
                    logger.info("找不到 House");
                }
            }catch (WrongContainException | IOException e){//已知错误，重试
                if(e instanceof HttpStatusException){
                    HttpStatusException ex = (HttpStatusException) e;
                    if(ex.getStatusCode() == 404){
                        houseImagePage.setCounter(houseImagePage.getCounter() + 1);
                    }
//                    System.out.println("爬取图片出错：" + ex.getMessage() + ex.getStatusCode() + "错误url，" + ex.getUrl() + "，爬取url:" + houseImagePage.getUrl());
                }

                if(houseImagePage.getCounter() <= 10){
                    getSender().tell(houseImagePage, ActorRef.noSender());//重试
                }
            }
            catch (Exception e){
//                e.printStackTrace();
                System.out.println("----------=" + houseImagePage.getUrl());
//                switchIp();
                if(houseImagePage.getCounter() < 10){
//                    System.out.println("爬取房源图片进行第" + houseImagePage.getCounter() + "次重试，" + houseImagePage.getUrl());
                    houseImagePage.setCounter(houseImagePage.getCounter() + 1);
                    getSender().tell(houseImagePage, getSelf());
                }else{
                    StringWriter errors = new StringWriter();
                    e.printStackTrace(new PrintWriter(errors));
                    logger.error(new StringBuilder()
                            .append("安居客图片爬取出错").append("\n")
                            .append("from url: ").append(houseImagePage.getUrl()).append("\n")
                            .append("e StackTrace: "+ errors));
                }
        }
    }

}
